package com.tedu.api.list;

import com.sun.deploy.net.MessageHeader;
import org.junit.Test;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

/**
 * 包位置:java.util
 * Map与Collection同等级项级接口
 * Map映射接口
 * 作用:一个元素由两个对象构成，分别为Key[键]和Value[值]构成，
 *     获取数据:用键取值,通常与数据库搭配，获取字段下的值
 * 特点:无序、无下标、键不可以重复【唯一性]、值可以重复
 * Map接口---无法直接实例化【创建]对象---实现类
 * HashMap[常用]:由哈希算法底层实现，存储性能快，键可以存null，但只允许一
 *              主要是通过键找值
 * LinkedHashMap[不常用]：方法与HashMap，用于日志记录时间顺序
 * TreeMap[不用]:插入删除非常慢，多线程不安全，占用内存
 *  *                【算法：红黑树实现--需要进行树的旋转和调整以保持平衡】
 * Hashtable[不用]:jdk1.0，性能：插入删除非常慢，多线程不安全，占用内存
 *                【算法：哈希算法】
 * Hashtable被ConcurrentHashMap取代
 * ConcurrentHashMap[较为常用]:学习线程
 * 重点:Map接口中方法【Map接口方法与HashMap方法类似 90%]
 */
public class MapAPI {
    @Test
    public void testMap(){
        //创建Map映射接口---多态    键--->值 id--19870502265
        Map<Object,String> map=new HashMap<>();
        //键--->值添加元素:K-V
/**
 * put(" 键","值")	返回值:V value 值
 *作用:存键值对形态一组数据
 */
 map.put("西游记","孙悟空");
 map.put("水浒传","武松");
 map.put("红楼梦","林黛玉");
 map.put("三国志","诸葛亮");
 System.out.println("map映射存储数据:"+map);
 /**
 * get(E e)根据键找到对应值返回值:Vvalue
 * remove(K key)通过key删除一组键值对
 * size() 获取map的元素总数 返回值：int
 */

//找到map集合中武松的元素---V value 值
        String wusong=map.get("水浒传");
        System.out.println("通过键找到值:"+wusong);
        //get() 键不存在--返回指定默认值：基本类型、引用类型：null值
        String zhuge=map.get("三国志");
        System.out.println("通过键找到值:"+zhuge);
        map.remove("三国志");
        System.out.println("删除后映射：+map");
        System.out.println("获取map元素总数："+map.size());
        /**
         * contains()
         * 作用：判断map中元素 “对象:键”是否存在
         * containsValue()
         * 作用：判断map中元素 “对象:值”是否存在
         */
        boolean bk=map.containsKey("红楼梦");
        System.out.println("map元素：键"+bk);
        boolean bv=map.containsKey("武松");
        System.out.println("map元素：值"+bk);
    }
    /**
     * map元素遍历 键---->值
     * keySet() 获取map元素中的所有键
     * values() 获取map元素中的所有值
     * entrySet() 获取map元素中的所有键与值
     */
    @Test
    public void testKYE() {
        //创建map映射集合
        Map<Object, String> map = new HashMap<>();
        map.put("默", "那英");
        map.put("告白气球", "周杰伦");
        map.put("套马杆", "乌拉图雅");
        map.put("丑八怪", "薛之谦");
//1.获取map集合元素中键数据keySet() 返回值:Set集合
        Set<Object> sets = map.keySet();
        //1.2遍历从map元素中获取的键--数据
        for (Object keys : sets) {
            System.out.println("输出map元素中:" + keys);
        }
        //2.获取map集合元素中值数据values()	返回值:Collection
        Collection<String> cs = map.values();
        //2.2遍历从map元素中获取的值--数据
        for (String values : cs) {
            System.out.println("输出map元素中:" + values);
        }
        //3.获取map集合元素【entrys】中 数据：键与值 entrySet()
        //返回值：Set<Map.Entry<K,V>>
        //Map.Entry<K,V> 保存map元素一组数据，表示：一组entry
        //Entry内部接口：保存map元素中所有组数据！所有Map.Entry
        Set<Map.Entry<Object, String>> entries = map.entrySet();
        //获取map映射集合所有元素【entry】
        //3.遍历map所有键和值【所有entry/元素/数据---成对】
        for (Map.Entry<Object, String> entry : entries) {
            Object keys = entry.getKey();
            //3.3获取值	getValue注意:类型
            String values = entry.getValue();
            //3.4 打印
            System.out.println(keys + " " + values);
        }
    }
        /**
         * forEach(new BiConsumer()) 遍历map中所有对元素/entry
         * 理解:for+entrySet()集合= forEach()
         * BiConsumer接口参数传入
         * 理解: 针对map存储问题--封装接口--提供方法:accept()一组entry
         */
            @Test
            public void testForEach(){
              //创建Map映射集合
                Map<Object,String> map=new HashMap<>();
                map.put("默","那英");map.put("告白气球","周杰伦");
                map.put("套马杆","乌拉图雅");map.put("丑八怪","薛之谦");
          //Map映射集合--提供一套方法：forEach()
        map.forEach(new BiConsumer<Object, String>() {
          //accept(K,V)方法：获取到Entry中--每组entry
            //K--键 V--值
            @Override
            public void accept(Object key, String value) {
                System.out.println(key+" "+value);
            }
        });




}
    /**
     * HashMap 映射集合
     * HashMap中方法基本与Map方法一致
     * 作用:用来给HashMap映射集合
     * putIfAbsent()如果存入一组数据，
     * 不存在的键，插入HashMap
     * 存在的键，不插入HashMap
     * 哈希算法--唯一性
     *
     */
    @Test
    public void testHashMap() {
        //创建Map映射集合
        Map<Object, String> map = new HashMap<>();
        map.putIfAbsent("演员", "薛之谦");
        map.put("默", "那英");
        map.put("告白气球", "周杰伦");
        map.put("套马杆", "乌拉图雅");
        map.put("丑八怪", "薛之谦");
        System.out.println("HashMap存值" + map);


    }}